import { deepCopy } from '@/utils'
import elFormItems from '@/utils/formUtils'
export default {
  props: {
    fields: {
      type: Array,
      default: () => []
    },
    displayInner: Boolean,
    value: {
      type: Object,
      default: () => ({})
    },
    hideSubmit: {
      type: Boolean,
      default: false
    },
    validator: {
      type: Boolean,
      default: true
    },
    defaultSubmit: {
      type: Boolean,
      default: true
    },
    inline: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      form: {},
      rules: {},
      datatemp: new Date().getTime()
    }
  },
  created() {
    if (this.value) {
      this.form = deepCopy(this.value)
    }
    this.fields.forEach(i => {
      if (i.type === 'checkbox') this.form[i.prop] = []
    });
    this.form = { ...this.form }
  },
  watch: {
    form() {
      this.$emit('input', this.form)
    }
  },
  methods: {
    iniDefaultValue({ type, prop }) {
      if (type === 'checkbox') {
        return this.form[prop] || []
      }
      return this.form[prop]
    },
    fieldComponent(field) {
      const { type, label, prop, options = [] } = field
      const item = elFormItems.find(i => i.value === type)
      const children = options.map(o => {
        if (type === 'select') return <el-option props={o}></el-option>
        if (type === 'radio' && !o.is) o.is = 'el-radio'
        if (type === 'checkbox' && !o.is) o.is = 'el-checkbox'
        return this.$createElement(o.is, { attrs: { label: o.value } }, [o.label])
      })
      const props = {
        style: { width: '100%' },
        attrs: {
          value: this.iniDefaultValue(field),
          collapse: field.collapse, 
          placeholder: item?.placeholder ? item.placeholder + label : '',
          children: field.children,
          ...field.props,
        },
        on: {
          input: value => {
            this.form[prop] = value
            this.form = { ...this.form }
            this.$emit('change', value, prop, this.form)
          },
          'update:collapse': value => {
            field.collapse = value
          } 
        }
      }
      return this.$createElement(item?.is || type, props, children)
    },
    createValidator(validator) {
      return async (rule, value, callback) => {
        let result
        if (typeof validator === 'function') {
          result = validator(value, this.form)
        } else {
          result = await new Function('value', 'form', validator)(value, this.form)
        }
        if (typeof result === 'boolean' && result) {
          callback()
        } else {
          callback(result || '输入不合法')
        }
      }
    },
    createFields() {
      return this.fields.map(i => {
        const { validator, prop, width, show, label, labelWidth, required, error, showMessage, inlineMessage, size } = i 
        if ((typeof show === 'boolean' && !show) ||
        (typeof show === 'function' && !i.show(this.form)) || 
        (typeof show === 'string' && !new Function('form', show)(this.form))) {
          return
        }
        const rules = []
        const style = { width: width || '100%', float: this.inline ? 'left' : '', ...i.style }
        const props = { prop, label: label + ': ', labelWidth, required, error, showMessage, inlineMessage, size }
        if (required) {
          rules.push({ required: true, message: '请输入' + label, trigger: 'change' })
        }
        if (validator) {
          rules.push({ validator: this.createValidator(validator), trigger: 'change' })
        }
        return <el-form-item props={props} style={style} rules={rules}>{this.fieldComponent(i)}</el-form-item>
      })
    },
    async onSubmit() {
      try {
        await this.$refs.form.validate()
        this.$emit('submit', this.form, this)
      } catch (error) {
        console.log('onSubmit error', error)
      }
    },
    resetForm() {
      this.$refs.form.resetFields()
    },
    createButtons() {
      if (this.hideSubmit) return null
      return (
        <el-form-item key={this.datatemp}>
          <el-button type="primary" onClick={this.onSubmit}>提交</el-button>
          <el-button onClick={this.resetForm}>重置</el-button>
        </el-form-item>
      )
    },
  },
  render() {
    return <div>
      <el-form ref="form" props={{ ...this.$attrs, model: this.form }}>
        <div class={this.inline ? 'clearfix':''}>{this.createFields()}</div>
        {this.createButtons()}
      </el-form>
    </div>
  }
}